package org.jeik.beackBeans.admin;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;

import javax.faces.application.FacesMessage;

import org.jeik.beackBeans.BeansBase;
import org.jeik.common.Constants;
import org.jeik.controllers.MsgsController;
import org.jeik.controllers.NavigationController;
import org.jeik.controllers.NavigationRule;
import org.jeik.data.dao.DataException;
import org.jeik.data.models.Attachment;
import org.jeik.data.models.Service;
import org.jeik.data.models.ServiceParent;
import org.jeik.data.services.EmbassyServicesService;
import org.jeik.utils.Configs;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DualListModel;

/**
 * 
 * @author AAsha
 *
 */
@SuppressWarnings("serial")
public class EmbassyServicesHandlerBean extends BeansBase {
	
	//Constants
	private static final String DEFAULT_BODY = "<h3><a class=\"special-underline\">الأوراق المطلوبة</a></h3><div class=\"customList customTree\"><ul><li>النقطة</li></ul></div>" +
			"<h3><a class=\"special-underline\">ملاحظة</a></h3><div class=\"customList customTree\"><ul><li>النقطة</li></ul></div>" +
			"<h3><a class=\"special-underline\">الرسوم</a></h3><div class=\"customList customTree\"><ul><li>دينار كويتي</li></ul></div>";
	
	//Fields
	private List<ServiceParent> embassyParentServicesList = new ArrayList<ServiceParent>();
	private List<Service> embassyServicesList = new ArrayList<Service>();
	
	private ServiceParent serviceParent = new ServiceParent();
	private Service service = new Service();

	private DualListModel<Service> pickListServices;
    private List<Service> servicesSource = new ArrayList<Service>();  
    private List<Service> servicesTarget = new ArrayList<Service>();
    
    private List<File> uploadedFiles = new ArrayList<File>();
    private List<File> deletedFiles = new ArrayList<File>();

	/**
	 * 
	 */
	public EmbassyServicesHandlerBean() {
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void loadEmbassyParentServiceSummary() throws DataException{
		
		if(embassyParentServicesList == null || embassyParentServicesList.size() == 0){
			embassyParentServicesList = EmbassyServicesService.getInstance().loadEmbassyServicesParents();
		}
		
		NavigationController.navigate(NavigationRule.EMBASSY_PARENT_SERVICES_SUMMARY);
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void loadEmbassyServiceSummary() throws DataException{
		
		if(embassyServicesList == null || embassyServicesList.size() == 0){
			embassyServicesList = EmbassyServicesService.getInstance().loadEmbassyServices();
		}
		
		NavigationController.navigate(NavigationRule.EMBASSY_SERVICES_SUMMARY);
	}
	
	
	//==================================
	//==================================
	
	public void updateOrder() throws DataException{
		
		EmbassyServicesService.getInstance().updateServiceParentsOrder(embassyParentServicesList);
		
		Collections.sort(embassyParentServicesList);
		
		MsgsController.addFacesGlobalMessage(FacesMessage.SEVERITY_INFO, "تم تحديث الترتيب بنجاح");
	}
	
	/**
	 * 
	 * @throws DataException 
	 */
	public void preAddServiceParent() throws DataException{
		
		serviceParent = new ServiceParent();
		
		this.loadEmbassyServiceSummary();
		
		servicesSource.clear();
		servicesTarget.clear();
		servicesSource.addAll(embassyServicesList);
		setPickListServices(new DualListModel<Service>(servicesSource, servicesTarget));
		
		NavigationController.navigate(NavigationRule.ADD_EMBASSY_SERVICE_PARENT);
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void addEmbassyServiceParent() throws DataException{
		
		//Add Embassy Parent Service
		serviceParent.setRequests(pickListServices.getTarget());
		EmbassyServicesService.getInstance().addServiceParent(serviceParent);
		MsgsController.addFacesGlobalMessage(FacesMessage.SEVERITY_INFO, "تم اضافة الخدمة بنجاح");
		
		//Add the new service parent to cached list and navigate to summary.
		getEmbassyParentServicesList().add(serviceParent);
		
		//Sort List
		Collections.sort(getEmbassyParentServicesList());
		
		NavigationController.navigate(NavigationRule.EMBASSY_PARENT_SERVICES_SUMMARY);
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void preEditEmbassyParentService(ServiceParent service) throws DataException{
		
		serviceParent = service;
		this.loadEmbassyServiceSummary();
		
		servicesSource.clear();
		servicesTarget.clear();
		servicesSource.addAll(embassyServicesList);
		
		int i = 0;
		for(Service request:serviceParent.getRequests()){
			i = servicesSource.indexOf(request);
			servicesTarget.add(servicesSource.remove(i));
		}
		
		
		setPickListServices(new DualListModel<Service>(servicesSource, servicesTarget));
		
		NavigationController.navigate(NavigationRule.EDIT_EMBASSY_SERVICE_PARENT);
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void editEmbassyParentService() throws DataException{
		
		serviceParent.setRequests(getPickListServices().getTarget());
		EmbassyServicesService.getInstance().editServiceParent(serviceParent);
		MsgsController.addFacesGlobalMessage(FacesMessage.SEVERITY_INFO, "تم تعديل الخدمة بنجاح");
		
		//Add the edited service parent to cached list and navigate to summary.
		getEmbassyParentServicesList().remove(serviceParent);
		getEmbassyParentServicesList().add(serviceParent);
		
		//Sort List
		Collections.sort(getEmbassyParentServicesList());
		
		NavigationController.navigate(NavigationRule.EMBASSY_PARENT_SERVICES_SUMMARY);
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void deleteEmbassyParentService(ServiceParent service) throws DataException{
		
		EmbassyServicesService.getInstance().deleteServiceParent(service);
		MsgsController.addFacesGlobalMessage(FacesMessage.SEVERITY_INFO, "تم حذف الخدمة بنجاح");
		
		//Delete the service parent from cached list.
		getEmbassyParentServicesList().remove(service);
	}
	

	//=============================
	//=============================
	
	
	/**
	 * 
	 * @throws DataException 
	 */
	public void preAddService() throws DataException{
		service = new Service();
		service.setBody(DEFAULT_BODY);
		NavigationController.navigate(NavigationRule.ADD_EMBASSY_SERVICE);
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void addEmbassyService() throws DataException{
		
		//Add Embassy Service
		EmbassyServicesService.getInstance().addService(service);
		MsgsController.addFacesGlobalMessage(FacesMessage.SEVERITY_INFO, "تم اضافة الطلب بنجاح");
		
		//Realocate File from temp directory.
		for(File file:uploadedFiles){
			file.renameTo(new File(Configs.getConfigValue(Constants.Configs.FILES_DIR), file.getName()));
		}
		uploadedFiles.clear();
		
		//Add the new service to cached list and navigate to summary.
		getEmbassyServicesList().add(service);
		NavigationController.navigate(NavigationRule.EMBASSY_SERVICES_SUMMARY);
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void preEditEmbassyService(Service service) throws DataException{
		
		this.service = service;
		
		NavigationController.navigate(NavigationRule.EDIT_EMBASSY_SERVICE);
	}
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void editEmbassyService() throws DataException{
		
		EmbassyServicesService.getInstance().editService(service);
		
		MsgsController.addFacesGlobalMessage(FacesMessage.SEVERITY_INFO, "تم تعديل الطلب بنجاح");
		
		//Realocate uploaded files from temp directory.
		for(File file:uploadedFiles){
			file.renameTo(new File(Configs.getConfigValue(Constants.Configs.FILES_DIR), file.getName()));
		}
		uploadedFiles.clear();
		
		//Delete files.
		for(File file:deletedFiles){
			file.delete();
		}
		deletedFiles.clear();
		
		
		//Add the edited service to cached list and navigate to summary.
		getEmbassyServicesList().remove(service);
		getEmbassyServicesList().add(service);
		NavigationController.navigate(NavigationRule.EMBASSY_SERVICES_SUMMARY);

	}
	
	
	/**
	 * @throws DataException 
	 * 
	 */
	public void deleteEmbassyService(Service service) throws DataException{
		
		EmbassyServicesService.getInstance().deleteService(service);
		MsgsController.addFacesGlobalMessage(FacesMessage.SEVERITY_INFO, "تم حذف الطلب");
		
		//Delete Service Files
		for(Attachment attachment:service.getAttachments()){
			File file = new File(Configs.getConfigValue(Constants.Configs.FILES_DIR), attachment.getAttachmentFileName());
			file.delete();
		}
		
		//Delete the service from cached list.
		getEmbassyServicesList().remove(service);
	}
	
	/**
	 * 
	 * @param event
	 */
	public void handleFileUpload(FileUploadEvent event) {  
		
		File uploadedFile = null;
		
		try {
			
            File filesDir = new File(Configs.getConfigValue(Constants.Configs.TEMP_FILES_DIR));
            
            String fileName = event.getFile().getFileName();
            
            if(!fileName.matches("[a-zA-Z0-9]*.(gif|jpe?g|png|pdf)")){
            	MsgsController.addErrorMessage("اسم الملف غير صحيح, يجب ان يكون باللغة الانجليزية !");
            	return;
            }
            
            uploadedFile = new File(filesDir, fileName);
            
            InputStream inputStream = event.getFile().getInputstream();
            OutputStream out = new FileOutputStream(uploadedFile);
            
            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = inputStream.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            
            inputStream.close();
            out.flush();
            out.close();
            
            uploadedFiles.add(uploadedFile);
            
            service.getAttachments().add(new Attachment(Calendar.getInstance().getTimeInMillis(), fileName, uploadedFile.getName(), uploadedFile));
            
        } catch (IOException e) {
            e.printStackTrace();
        }
        
		MsgsController.addInfoMessage("تم رفع الملفات بنجاح");
    }
	
	/**
	 * 
	 * @param attachment
	 */
	public void deleteAttachment(Attachment attachment){
		
		//Covers the tmp files case.
		File file = attachment.getFile();
		if(file != null){
			uploadedFiles.remove(file);
			file.delete();
		}
		
		//Covers the edit case.
		file = new File(Configs.getConfigValue(Constants.Configs.FILES_DIR), attachment.getAttachmentFileName());
		if(file.exists()){
			deletedFiles.add(file);
		}
		
		MsgsController.addInfoMessage("تم حذف الملف بنجاح");
		
		service.getAttachments().remove(attachment);
		
	}
	
	
	//==========================================
	// Setters and Getters
	//==========================================
	
	/**
	 * 
	 * @return
	 */
	public List<ServiceParent> getEmbassyParentServicesList() {
		return embassyParentServicesList;
	}
	
	/**
	 * 
	 * @param embassyParentServicesList
	 */
	public void setEmbassyParentServicesList(
			List<ServiceParent> embassyParentServicesList) {
		this.embassyParentServicesList = embassyParentServicesList;
	}
	
	public void setEmbassyServicesList(List<Service> embassyServicesList) {
		this.embassyServicesList = embassyServicesList;
	}
	
	public List<Service> getEmbassyServicesList() {
		return embassyServicesList;
	}

	public ServiceParent getServiceParent() {
		return serviceParent;
	}

	public void setServiceParent(ServiceParent serviceParent) {
		this.serviceParent = serviceParent;
	}

	public DualListModel<Service> getPickListServices() {
		return pickListServices;
	}

	public void setPickListServices(DualListModel<Service> pickListServices) {
		this.pickListServices = pickListServices;
	}
	
	public Service getService() {
		return service;
	}

	public void setService(Service service) {
		this.service = service;
	}
	
}
